home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr26 / netprog.zip / NETPROG.TAR / lib / tcpopen.c < prev    next >
C/C++ Source or Header  |  1989-12-17  |  3KB  |  115 lines

  1. /*
  2.  * Open a TCP connection.
  3.  */
  4.  
  5. #include    "netdefs.h"
  6.  
  7. #include    <netinet/in.h>
  8. #include    <arpa/inet.h>
  9.  
  10. #ifndef    INADDR_NONE
  11. #define    INADDR_NONE    0xffffffff    /* should be in <netinet/in.h> */
  12. #endif
  13.  
  14. /*
  15.  * The following globals are available to the caller, if desired.
  16.  */
  17.  
  18. struct sockaddr_in    tcp_srv_addr;    /* server's Internet socket addr */
  19. struct servent        tcp_serv_info;    /* from getservbyname() */
  20. struct hostent        tcp_host_info;    /* from gethostbyname() */
  21.  
  22. int            /* return socket descriptor if OK, else -1 on error */
  23. tcp_open(host, service, port)
  24. char    *host;        /* name or dotted-decimal addr of other system */
  25. char    *service;    /* name of service being requested */
  26.             /* can be NULL, iff port > 0 */
  27. int    port;        /* if == 0, nothing special - use port# of service */
  28.             /* if < 0, bind a local reserved port */
  29.             /* if > 0, it's the port# of server (host-byte-order) */
  30. {
  31.     int        fd, resvport;
  32.     unsigned long    inaddr;
  33.     char        *host_err_str();
  34.     struct servent    *sp;
  35.     struct hostent    *hp;
  36.  
  37.     /*
  38.      * Initialize the server's Internet address structure.
  39.      * We'll store the actual 4-byte Internet address and the
  40.      * 2-byte port# below.
  41.      */
  42.  
  43.     bzero((char *) &tcp_srv_addr, sizeof(tcp_srv_addr));
  44.     tcp_srv_addr.sin_family = AF_INET;
  45.  
  46.     if (service != NULL) {
  47.         if ( (sp = getservbyname(service, "tcp")) == NULL) {
  48.             err_ret("tcp_open: unknown service: %s/tcp", service);
  49.             return(-1);
  50.         }
  51.         tcp_serv_info = *sp;            /* structure copy */
  52.         if (port > 0)
  53.             tcp_srv_addr.sin_port = htons(port);
  54.                             /* caller's value */
  55.         else
  56.             tcp_srv_addr.sin_port = sp->s_port;
  57.                             /* service's value */
  58.     } else {
  59.         if (port <= 0) {
  60.             err_ret("tcp_open: must specify either service or port");
  61.             return(-1);
  62.         }
  63.         tcp_srv_addr.sin_port = htons(port);
  64.     }
  65.  
  66.     /*
  67.      * First try to convert the host name as a dotted-decimal number.
  68.      * Only if that fails do we call gethostbyname().
  69.      */
  70.  
  71.     if ( (inaddr = inet_addr(host)) != INADDR_NONE) {
  72.                         /* it's dotted-decimal */
  73.         bcopy((char *) &inaddr, (char *) &tcp_srv_addr.sin_addr,
  74.                     sizeof(inaddr));
  75.         tcp_host_info.h_name = NULL;
  76.  
  77.     } else {
  78.         if ( (hp = gethostbyname(host)) == NULL) {
  79.             err_ret("tcp_open: host name error: %s %s",
  80.                         host, host_err_str());
  81.             return(-1);
  82.         }
  83.         tcp_host_info = *hp;    /* found it by name, structure copy */
  84.         bcopy(hp->h_addr, (char *) &tcp_srv_addr.sin_addr,
  85.             hp->h_length);
  86.     }
  87.  
  88.     if (port >= 0) {
  89.         if ( (fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
  90.             err_ret("tcp_open: can't create TCP socket");
  91.             return(-1);
  92.         }
  93.  
  94.     } else if (port < 0) {
  95.         resvport = IPPORT_RESERVED - 1;
  96.         if ( (fd = rresvport(&resvport)) < 0) {
  97.             err_ret("tcp_open: can't get a reserved TCP port");
  98.             return(-1);
  99.         }
  100.     }
  101.  
  102.     /*
  103.      * Connect to the server.
  104.      */
  105.  
  106.     if (connect(fd, (struct sockaddr *) &tcp_srv_addr,
  107.                         sizeof(tcp_srv_addr)) < 0) {
  108.         err_ret("tcp_open: can't connect to server");
  109.         close(fd);
  110.         return(-1);
  111.     }
  112.  
  113.     return(fd);    /* all OK */
  114. }
  115.